/**********************************************************************************************************************
 * Copyright (c) Prophesee S.A.                                                                                       *
 *                                                                                                                    *
 * Licensed under the Apache License, Version 2.0 (the "License");                                                    *
 * you may not use this file except in compliance with the License.                                                   *
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0                                 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed   *
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                      *
 * See the License for the specific language governing permissions and limitations under the License.                 *
 **********************************************************************************************************************/

#ifndef METAVISION_HAL_I_ANTIFLICKER_MODULE_H
#define METAVISION_HAL_I_ANTIFLICKER_MODULE_H

#include <cstdint>
#include <utility>

#include "metavision/hal/facilities/i_registrable_facility.h"

namespace Metavision {

/// @brief Anti-flicker module
class I_AntiFlickerModule : public I_RegistrableFacility<I_AntiFlickerModule> {
public:
    /// @brief AntiFlicker filter mode.
    ///
    /// BAND_PASS removes all events outside of the band sequence defined.
    ///
    /// BAND_STOP removes all frequencies between min and max.
    enum AntiFlickerMode { BAND_PASS, BAND_STOP };

    /// @brief Toggles Anti-flicker activation
    /// @param b Desired state. b = true means Anti-flicker active, and b = false means Anti-flicker inactive.
    /// @note When Anti-flicker is inactive, all the events generated by the sensor are transmitted. Potential
    /// bandwidth limitation might occur.
    /// @return true on success
    virtual bool enable(bool b) = 0;

    /// @brief Returns Anti-flicker activation state
    /// @return The Anti-flicker state
    virtual bool is_enabled() const = 0;

    /// @brief Sets anti-flicker parameters.
    ///
    /// Defines the frequency band to be kept or removed in the range [min_supported_freq, max_supported_freq] Hz
    /// where minimum and maximum supported frequencies can be obtained with @ref get_min_supported_frequency
    ///
    /// @param low_freq Lowest frequency of the band (in Hz)
    /// @param high_freq Highest frequency of the band (in Hz)
    /// @note Facility might be reset if parameter is changed while enabled
    /// @throw exception if frequencies are outside of the range [min_supported_freq, max_supported_freq] Hz
    /// @return true on success
    virtual bool set_frequency_band(uint32_t low_freq, uint32_t high_freq) = 0;

    /// @brief Gets lowest frequency of the band
    virtual uint32_t get_band_low_frequency() const = 0;

    /// @brief Gets highest frequency of the band
    virtual uint32_t get_band_high_frequency() const = 0;

    /// @brief Gets frequency band setting
    std::pair<uint32_t, uint32_t> get_frequency_band() const;

    /// @brief Gets minimum supported frequency
    virtual uint32_t get_min_supported_frequency() const = 0;

    /// @brief Gets maximum supported frequency
    virtual uint32_t get_max_supported_frequency() const = 0;

    /// @brief Sets the anti-flicker filtering mode
    /// @param mode Anti-flicker mode
    /// @note Facility might be reset if parameter is changed while enabled
    /// @return true on success
    virtual bool set_filtering_mode(AntiFlickerMode mode) = 0;

    /// @brief Gets filtering mode
    virtual AntiFlickerMode get_filtering_mode() const = 0;

    /// @brief Sets the duty cycle for Antiflicker filter
    /// @param duty_cycle Target duty cycle of Antiflicker filter as a percentage
    /// @return true on success, false otherwise
    virtual bool set_duty_cycle(float duty_cycle) = 0;

    /// @brief Gets the duty cycle for Antiflicker filter
    /// @return The duty cycle for Antiflicker filter as a percentage
    virtual float get_duty_cycle() const = 0;

    /// @brief Gets minimum supported duty cycle value
    virtual float get_min_supported_duty_cycle() const = 0;

    /// @brief Gets maximum supported duty cycle value
    virtual float get_max_supported_duty_cycle() const = 0;

    /// @brief Sets the threshold above which Antiflicker should start filtering
    /// @param threshold Number of successive periodic event bursts falling
    ///        within the frequency band
    /// @return true on success, false otherwise
    virtual bool set_start_threshold(uint32_t threshold) = 0;

    /// @brief Sets the threshold below which Antiflicker should stop filtering
    /// @param threshold Number of successive periodic event bursts falling
    ///        within the frequency band
    /// @return true on success, false otherwise
    virtual bool set_stop_threshold(uint32_t threshold) = 0;

    /// @brief Gets the Antiflicker start threshold
    /// @return The threshold in number of bursts
    virtual uint32_t get_start_threshold() const = 0;

    /// @brief Gets the Antiflicker stop threshold
    /// @return The threshold in number of bursts
    virtual uint32_t get_stop_threshold() const = 0;

    /// @brief Gets the Antiflicker start threshold minimum supported value
    /// @return Start threshold minimum supported value
    virtual uint32_t get_min_supported_start_threshold() const = 0;

    /// @brief Gets the Antiflicker start threshold maximum supported value
    /// @return Start threshold maximum supported value
    virtual uint32_t get_max_supported_start_threshold() const = 0;

    /// @brief Gets the Antiflicker stop threshold minimum supported value
    /// @return Stop threshold minimum supported value
    virtual uint32_t get_min_supported_stop_threshold() const = 0;

    /// @brief Gets the Antiflicker stop threshold maximum supported value
    /// @return Stop threshold maximum supported value
    virtual uint32_t get_max_supported_stop_threshold() const = 0;
};

} // namespace Metavision

#endif // METAVISION_HAL_I_ANTIFLICKER_MODULE_H
